package com.yc.cloud.admin.config;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

@Configuration
public class WebClientConfig {

    @Resource
    private MediaKitApiProperties mediaKitApiProperties;

    @Resource
    private SipServerProperties sipServerProperties;

    @Resource
    private FaceRecognitionProperties faceRecognitionProperties;

    /**
     * 通用WebClient Bean配置
     * 设置了连接超时、读写超时、最大内存大小等参数
     * 添加了请求和响应日志过滤器
     */
    @Bean
    public WebClient webClient() {
        // 设置内存限制为16MB（默认为256KB）
        ExchangeStrategies strategies = ExchangeStrategies.builder()
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
                .build();

        // 配置HTTP客户端参数
        HttpClient httpClient = HttpClient.create()
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 连接超时5秒
                .responseTimeout(Duration.ofSeconds(5)) // 响应超时5秒
                .doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler(5, TimeUnit.SECONDS)) // 读超时5秒
                        .addHandlerLast(new WriteTimeoutHandler(5, TimeUnit.SECONDS))); // 写超时5秒

        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .exchangeStrategies(strategies)
                .filter(logRequest())
                .filter(logResponse())
                .build();
    }

    /**
     * 记录请求日志的过滤器
     */
    private ExchangeFilterFunction logRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            // 只在DEBUG级别记录详细请求信息
            if (org.slf4j.LoggerFactory.getLogger(WebClientConfig.class).isDebugEnabled()) {
                StringBuilder sb = new StringBuilder("Request: \n");
                sb.append("Method: ").append(clientRequest.method()).append("\n");
                sb.append("URL: ").append(clientRequest.url()).append("\n");
                clientRequest.headers().forEach((name, values) -> 
                    values.forEach(value -> sb.append(name).append(": ").append(value).append("\n")));
                org.slf4j.LoggerFactory.getLogger(WebClientConfig.class).debug(sb.toString());
            }
            return Mono.just(clientRequest);
        });
    }

    /**
     * 记录响应日志的过滤器
     */
    private ExchangeFilterFunction logResponse() {
        return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
            // 只在DEBUG级别记录响应状态
            if (org.slf4j.LoggerFactory.getLogger(WebClientConfig.class).isDebugEnabled()) {
                org.slf4j.LoggerFactory.getLogger(WebClientConfig.class)
                    .debug("Response Status: {}", clientResponse.statusCode());
            }
            return Mono.just(clientResponse);
        });
    }

    /**
     * MediaKit API专用的WebClient Bean
     * 预配置了MediaKit服务的基础URL，避免每次请求都重复构建
     */
    @Bean("mediaKitWebClient")
    public WebClient mediaKitWebClient() {
        // 设置内存限制为16MB（默认为256KB）
        ExchangeStrategies strategies = ExchangeStrategies.builder()
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
                .build();

        // 配置HTTP客户端参数
        HttpClient httpClient = HttpClient.create()
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) // MediaKit连接超时10秒
                .responseTimeout(Duration.ofSeconds(30)) // MediaKit响应超时30秒（截图可能需要更长时间）
                .doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler(30, TimeUnit.SECONDS)) // 读超时30秒
                        .addHandlerLast(new WriteTimeoutHandler(10, TimeUnit.SECONDS))); // 写超时10秒

        // 构建专用的MediaKit WebClient，预设基础URL
        String baseUrl = String.format("%s://%s:%d", 
                mediaKitApiProperties.getScheme(),
                mediaKitApiProperties.getHost(),
                mediaKitApiProperties.getPort());

        return WebClient.builder()
                .baseUrl(baseUrl)
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .exchangeStrategies(strategies)
                .filter(logRequest())
                .filter(logResponse())
                .build();
    }

    /**
     * SIP信令服务器API专用的WebClient Bean
     * 预配置了SIP信令服务器的基础URL和认证信息
     */
    @Bean("sipServerWebClient")
    public WebClient sipServerWebClient() {
        // 设置内存限制为16MB（默认为256KB）
        ExchangeStrategies strategies = ExchangeStrategies.builder()
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
                .build();

        // 配置HTTP客户端参数
        HttpClient httpClient = HttpClient.create()
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) // SIP服务器连接超时10秒
                .responseTimeout(Duration.ofSeconds(15)) // SIP服务器响应超时15秒
                .doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler(15, TimeUnit.SECONDS)) // 读超时15秒
                        .addHandlerLast(new WriteTimeoutHandler(10, TimeUnit.SECONDS))); // 写超时10秒

        // 构建专用的SIP信令服务器WebClient，预设基础URL
        String baseUrl = String.format("%s://%s:%d%s", 
                sipServerProperties.getScheme(),
                sipServerProperties.getHost(),
                sipServerProperties.getPort(),
                sipServerProperties.getApiBasePath());

        return WebClient.builder()
                .baseUrl(baseUrl)
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .exchangeStrategies(strategies)
                .filter(logRequest())
                .filter(logResponse())
                .filter(authenticationFilter()) // 添加认证过滤器
                .build();
    }

    /**
     * 人脸识别服务专用的WebClient Bean
     * 预配置了人脸识别服务的基础URL和超时参数
     */
    @Bean("faceRecognitionWebClient")
    public WebClient faceRecognitionWebClient() {
        // 设置内存限制为16MB
        ExchangeStrategies strategies = ExchangeStrategies.builder()
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
                .build();

        // 配置HTTP客户端参数
        HttpClient httpClient = HttpClient.create()
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 
                        faceRecognitionProperties.getConnectTimeout()) // 连接超时
                .responseTimeout(Duration.ofMillis(
                        faceRecognitionProperties.getReadTimeout())) // 响应超时
                .doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler(
                                faceRecognitionProperties.getReadTimeout(), TimeUnit.MILLISECONDS))
                        .addHandlerLast(new WriteTimeoutHandler(
                                faceRecognitionProperties.getConnectTimeout(), TimeUnit.MILLISECONDS)));

        // 构建专用的人脸识别WebClient，预设基础URL
        return WebClient.builder()
                .baseUrl(faceRecognitionProperties.getBaseUrl())
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .exchangeStrategies(strategies)
                .filter(logRequest())
                .filter(logResponse())
                .build();
    }

    /**
     * SIP服务器认证过滤器
     * 自动为请求添加认证头
     */
    private ExchangeFilterFunction authenticationFilter() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            // 检查是否启用认证
            if (!sipServerProperties.getAuth().getEnabled()) {
                return Mono.just(clientRequest);
            }
            
            // 构建带认证头的请求
            var requestBuilder = ClientRequest.from(clientRequest);
            
            String authType = sipServerProperties.getAuth().getType();
            if ("jwt".equalsIgnoreCase(authType) && sipServerProperties.getAuth().getToken() != null) {
                // JWT Token认证
                requestBuilder.header(sipServerProperties.getAuth().getTokenHeader(), 
                        sipServerProperties.getAuth().getToken());
            } else if ("api-key".equalsIgnoreCase(authType) && sipServerProperties.getAuth().getApiKey() != null) {
                // API Key认证
                requestBuilder.header(sipServerProperties.getAuth().getApiKeyHeader(), 
                        sipServerProperties.getAuth().getApiKey());
            }
            
            return Mono.just(requestBuilder.build());
        });
    }
}